
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using SimpleJSON;

namespace HD
{
	public class CachedFactory<E, R> : Factory<E, R> where R : class, ICacheable
	{
		Dictionary<Type, Queue<R>> mCachedDict = new Dictionary<Type, Queue<R>>();

		public CachedFactory()
		{
		}

		protected override R Create(E enumType, Object arg, JSONClass dataDict)
		{
			DebugUtil.Assert(mTypeDict.ContainsKey(enumType));
			
			mArgs[0] = arg;
			Type valueType = Type.GetType(mTypeDict[enumType]);

			ICacheable instance;
			if (mCachedDict.ContainsKey(valueType) && mCachedDict[valueType].Count > 0){
				instance = mCachedDict[valueType].Dequeue();
			}
			else{
				instance = Activator.CreateInstance(valueType, mArgs) as R;
			}

			instance.OnCreate(arg);

			if (dataDict != null)
			{
				FieldInfo[] fi = valueType.GetFields(BindingFlags.Instance | BindingFlags.Public);
				
				foreach (FieldInfo m in fi)
				{
					HD.Reflection.SetFieldValue(instance, m, dataDict[m.Name]);
				}
			}
			
			return instance as R;
		}
	
		public void Recycle(R instance)
		{
			Type valueType = instance.GetType();

			if (!mCachedDict.ContainsKey(valueType))
				mCachedDict[valueType] = new Queue<R>();

			instance.OnRecycle();
			mCachedDict[valueType].Enqueue(instance);
		}
	}
}